﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;

namespace AgileDevTool.Helpers
{
    public class SecurityHelper
    {
        /// <summary>
        /// 获取MD5加密的字符串(Unicode编码)
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public static string GetMD5String(string input)
        {
            return GetMD5String(input, Encoding.UTF8);
        }

        /// <summary>
        /// 获取MD5加密的字符串(指定编码)
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public static string GetMD5String(string input, Encoding enc)
        {
            if (string.IsNullOrEmpty(input))
            {
                return "";
            }

            var md5 = new MD5CryptoServiceProvider();
            var source = enc.GetBytes(input);
            var hashed = md5.ComputeHash(source);
            var sb = new StringBuilder();

            for (int i = 0; i < hashed.Length; i++)
            {
                sb.Append(hashed[i].ToString("x2"));
            }

            return sb.ToString();
        }

        /// <summary>
        /// 获取SHA1加密的字符串(Unicode编码)
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public static string GetSHA1String(string input)
        {
            return GetSHA1String(input, Encoding.UTF8);
        }

        /// <summary>
        /// 获取SHA1加密的字符串(指定编码)
        /// </summary>
        /// <param name="input"></param>
        /// <param name="enc"></param>
        /// <returns></returns>
        public static string GetSHA1String(string input, Encoding enc)
        {
            if (string.IsNullOrEmpty(input))
            {
                return "";
            }

            var sha1 = new SHA1CryptoServiceProvider();
            var source = enc.GetBytes(input);
            var hashed = sha1.ComputeHash(source);
            var sb = new StringBuilder();

            for (int i = 0; i < hashed.Length; i++)
            {
                sb.Append(hashed[i].ToString("x2"));
            }

            return sb.ToString();
        }

        /// <summary>
        /// 获取SHA256加密的字符串(Unicode编码)
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public static string GetSHA256String(string input)
        {
            return GetSHA256String(input, Encoding.UTF8);
        }

        /// <summary>
        /// 获取SHA256加密的字符串(指定编码)
        /// </summary>
        /// <param name="input"></param>
        /// <param name="enc"></param>
        /// <returns></returns>
        public static string GetSHA256String(string input, Encoding enc)
        {
            if (string.IsNullOrEmpty(input))
            {
                return "";
            }

            var sha256 = new SHA256CryptoServiceProvider();
            var source = enc.GetBytes(input);
            var hashed = sha256.ComputeHash(source);
            var sb = new StringBuilder();

            for (int i = 0; i < hashed.Length; i++)
            {
                sb.Append(hashed[i].ToString("x2"));
            }

            return sb.ToString();
        }

        public static string AESEncrypt(string input, string key, string iv)
        {
            var bytes1 = Encoding.UTF8.GetBytes(key);
            var bytes2 = Encoding.UTF8.GetBytes(iv);
            var bytes = Encoding.UTF8.GetBytes(input);
            var aes = Rijndael.Create();
            using (var ms = new MemoryStream())
            {
                using (var cs = new CryptoStream(ms, aes.CreateEncryptor(bytes1, bytes2), CryptoStreamMode.Write))
                {
                    cs.Write(bytes, 0, bytes.Length);
                    cs.FlushFinalBlock();
                    return Convert.ToBase64String(ms.ToArray());
                }
            }
        }

        public static string AESDecrypt(string input, string key, string iv)
        {
            var bytes1 = Convert.FromBase64String(key);
            var bytes2 = Convert.FromBase64String(iv);
            var bytes = Convert.FromBase64String(input);
            var aes = Rijndael.Create();
            using (var ms = new MemoryStream())
            {
                using (var cs = new CryptoStream(ms, aes.CreateDecryptor(bytes1, bytes2), CryptoStreamMode.Write))
                {
                    cs.Write(bytes, 0, bytes.Length);
                    cs.FlushFinalBlock();
                    return Encoding.UTF8.GetString(ms.ToArray());
                }
            }
        }

        public static string DESEncrypt(string input, string key, string iv)
        {
            var bytes = Encoding.UTF8.GetBytes(input);
            using (var provider = new DESCryptoServiceProvider
            {
                Key = Encoding.ASCII.GetBytes(key),
                IV = Encoding.ASCII.GetBytes(iv)
            })
            {
                using (var ms = new MemoryStream())
                {
                    using (var cs = new CryptoStream(ms, provider.CreateEncryptor(), CryptoStreamMode.Write))
                    {
                        cs.Write(bytes, 0, bytes.Length);
                    }
                    return Convert.ToBase64String(ms.ToArray());
                }
            }
        }

        public static string DESDecrypt(string input, string key, string iv)
        {
            var bytes = Convert.FromBase64String(input);
            using (var provider = new DESCryptoServiceProvider
            {
                Key = Encoding.ASCII.GetBytes(key),
                IV = Encoding.ASCII.GetBytes(iv)
            })
            {
                using (var ms = new MemoryStream())
                {
                    using (var cs = new CryptoStream(ms, provider.CreateDecryptor(), CryptoStreamMode.Write))
                    {
                        cs.Write(bytes, 0, bytes.Length);
                    }
                    return Encoding.UTF8.GetString(ms.ToArray());
                }
            }
        }

        public static string Base64Encrypt(string input)
        {
            if (string.IsNullOrEmpty(input))
            {
                return input;
            }

            var bytes = Encoding.UTF8.GetBytes(input);
            return Convert.ToBase64String(bytes);
        }

        public static string Base64Decrypt(string input)
        {
            if (string.IsNullOrEmpty(input))
            {
                return input;
            }

            var bytes = Convert.FromBase64String(input);
            return Encoding.UTF8.GetString(bytes);
        }
    }
}
